package io.gitee.mingbaobaba.security.core.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import io.gitee.mingbaobaba.security.core.exception.SecurityBaseException;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.TimeZone;

/**
 * <p>json工具</p>
 *
 * @author yingsheng.ye
 * @version 1.0.0
 * @since 2023/9/9 20:34
 */
public class JsonUtil {

    private JsonUtil() {

    }

    /**
     * 获取 ObjectMapper 对象
     *
     * @return {@link ObjectMapper}
     */
    public static ObjectMapper getObjectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        // 指定时区
        objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));
        // 日期类型字符串处理
        objectMapper.setDateFormat(new SimpleDateFormat(DateUtil.FORMAT_DATETIME_PATTERN));
        // Java8日期日期处理
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        //LocalDateTime统一返回yyyy-MM-dd HH:mm:ss格式
        javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DateUtil.FORMAT_DATETIME_PATTERN)));
        //LocalDate统一返回yyyy-MM-dd格式
        javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DateUtil.FORMAT_DATE_PATTERN)));
        //LocalTime统一返回HH:mm:ss格式
        javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DateUtil.FORMAT_TIME_PATTERN)));
        //前端传入yyyy-MM-dd HH:mm:ss格式日期解析为LocalDateTime
        javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DateUtil.FORMAT_DATETIME_PATTERN)));
        //前端传入yyyy-MM-dd格式日期解析为LocalDate
        javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DateUtil.FORMAT_DATE_PATTERN)));
        //前端传入HH:mm:ss格式日期解析为LocalTime
        javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DateUtil.FORMAT_TIME_PATTERN)));
        objectMapper.registerModule(javaTimeModule);
        return objectMapper;
    }

    /**
     * 对象转json
     *
     * @param obj 对象
     * @return String
     */
    public static String objectToJsonStr(Object obj) {
        ObjectMapper objectMapper = getObjectMapper();
        String str;
        try {
            str = objectMapper.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            throw new SecurityBaseException(String.format("对象转JSON失败：%s", e.getMessage()));
        }
        return str;
    }

    /**
     * json转对象
     *
     * @param str    json字符串
     * @param tClass 类型
     * @param <T>    泛型
     * @return T
     */
    public static <T> T jsonStrToObject(String str, Class<T> tClass) {
        ObjectMapper objectMapper = getObjectMapper();
        try {
            return objectMapper.readValue(str, tClass);
        } catch (JsonProcessingException e) {
            throw new SecurityBaseException(String.format("JSON转对象失败：%s", e.getMessage()));
        }
    }

    /**
     * json转对象
     *
     * @param str    json字符串
     * @param tClass 类型
     * @param <T>    泛型
     * @return T
     */
    public static <T> T jsonStrToObject(String str, TypeReference<T> tClass) {
        ObjectMapper objectMapper = getObjectMapper();
        try {
            return objectMapper.readValue(str, tClass);
        } catch (JsonProcessingException e) {
            throw new SecurityBaseException(String.format("JSON转对象失败：%s", e.getMessage()));
        }
    }
}
